/**
 * 
 */
package org.xserver.core.command;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.ResourceBundle;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.xserver.AppSettings;
import org.xserver.Application;

/**
 * @author jkonopka
 * 
 */
public class SettingsFileInitializeCommand implements ICommand {

	/**
	 * 
	 */
	private static final long serialVersionUID = -594001896210247882L;
	private final Logger log = Logger.getLogger(getClass());
	private final Properties properties = new Properties();
	private final ResourceBundle bundle = ResourceBundle.getBundle("settings");

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jserver.command.ICommand#execute()
	 */
	@Override
	public void execute() throws Exception {
		log.debug("entering execute");

		if (!getUserSettingsFile().exists()) {
			createSettings();
		} else {
			updateSettings();
		}

		writeProperties();

		log.debug("leaving execute");
	}

	/**
	 * @throws Exception Errorhandling
	 */
	private void createSettings() throws Exception {
		log.debug("entering createSettings");

		final Enumeration<String> keys = bundle.getKeys();
		while (keys.hasMoreElements()) {
			final String key = keys.nextElement();
			properties.put(key, bundle.getString(key));
		}

		log.debug("leaving createSettings");
	}

	/**
	 * @throws Exception Errorhandling
	 */
	private void updateSettings() throws Exception {
		log.debug("entering updateSettings");

		final Properties currents = AppSettings.getProperties();
		properties.putAll(currents);
		final Enumeration<String> keys = bundle.getKeys();
		while (keys.hasMoreElements()) {
			final String key = keys.nextElement();
			if (currents.getProperty(key) == null) {
				final String value = bundle.getString(key);
				log.info(String.format("key=%s,value=%s", key, value));
				properties.put(key, value);
			}
		}

		log.debug("leaving updateSettings");
	}

	/**
	 * @return File with path to user settings file
	 */
	private File getUserSettingsFile() {
		return new File(Application.getUserSettingsFilename());
	}

	/**
	 * @throws IOException Errorhandling
	 */
	private synchronized void writeProperties() throws IOException {
		OutputStream os = null;
		try {
			os = new FileOutputStream(getUserSettingsFile());
			properties.storeToXML(os, getComment());
		} finally {
			IOUtils.closeQuietly(os);
		}
	}

	/**
	 * @return comment for settings file header
	 */
	private String getComment() {
		final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		return df.format(new Date());
	}

}
